/*
Programa de Tiago Falcao RA046802
*/
#include "imagem.h"

/* Cria uma nova imagem vazia. */
Image *CreateImage(int ncols, int nrows) {
  Image * aux;
  aux=malloc(sizeof(Image));
  aux->ncols=ncols;
  aux->nrows=nrows;
  aux->val=calloc(ncols*nrows,sizeof(int));
  return aux; /* temporario */
}

/* Destroi uma imagem e coloca NULL na variavel *img. */
void DestroyImage(Image **img) {
	if(*img){
		free((*img)->val);
		free(*img);
		*img=NULL;
	}
}

/* Carrega a imagem PGM P5 ou PGM P2. Considerar sempre
 * profundidade de 8 bits. */
Image *ReadImage(char *filename) {
	FILE * aux;
	char p;
	int tipo,col,lin,max,tam,c=0;
	Image * nova;
	aux=fopen(filename,"r");
	fscanf(aux,"%c%d\n",&p,&tipo);
	fscanf(aux,"%d %d\n",&col,&lin);
	nova=CreateImage(col,lin);
	fscanf(aux,"%d\n",&max);
	tam=lin*col;
	if(tipo==2){
		for(c=0;c<tam;c++){
			fscanf(aux,"%d ",&(nova->val[c]));
		}
	}else if(tipo==5){
		for(c=0;c<tam;c++){
			fread(&(nova->val[c]),sizeof(char),1,aux);
		}
	}
	fclose(aux);
  return nova; /* temporario */
}

/* Imprime a imagem no formato PGM P2. Considerar sempre
 * profundidade de 8 bits. */
void PrintImage(Image *img) {
	int c1=0, c2=0, tam=((img->ncols)*(img->nrows));
	if(! img){return;}
	printf("P2\n");
	printf("%d %d\n255\n",(img->ncols),(img->nrows));
	while(c1<tam){
		printf("%d",img->val[c1]);
		c1++;
		c2++;
		if((c1==tam)||(c2==10)){
			printf("\n");
			c2=0;
		}else{
			printf(" ");
		}
	}
}
void MovImage(Image *img) {
	int l=0, c=0;
	int b=0;
	while(c<=img->ncols){
		l=0;
		while(l<=img->nrows){
		}
	}
}
		
/* Calcula a media dos brilhos. */
float MeanValue(Image *img) {
	int t=0;
	int c=0,tam=((img->ncols)*(img->nrows));
	while(c<tam){
		t+=(img->val[c]);
		c++;
	}
	return (((float)t)/tam);
}

/* Calcula o negativo, alterando a propria imagem. */
void Negative(Image *img) {
	int c=0,tam=((img->ncols)*(img->nrows));
	while(c<tam){
		img->val[c]=255-(img->val[c]);
		c++;
	}
}

/* Limiariza a imagem, alterando a propria imagem. Os valores
 * dos pixels da imagem limiarizada devem ser 0 ou 255. */
void Threshold(Image *img, int thr) {
	int c=0,tam=((img->ncols)*(img->nrows));
	while(c<tam){
		if(img->val[c]>thr){
			img->val[c]=255;
		}else{
			img->val[c]=0;
		}
		c++;
	}
}

/* Calcula o histograma normalizado da imagem e retorna
 * um vetor com os valores. O indice do vetor representa o
 * valor de brilho. */
float *Histogram(Image *img) {
	float * vet;
	vet=calloc(256,sizeof(float));
	int c=0,tam=((img->ncols)*(img->nrows));
	while(c<tam){
		vet[img->val[c]]++;
		c++;
	}
	for(c=0;c<256;c++){
		vet[c]/=tam;
	}
  return vet;
}

/* Calcula o histograma normalizado acumulado da imagem e retorna
 * um vetor com os valores. O indice do vetor representa o
 * valor de brilho. */
float *AccHistogram(Image *img) {
	int c;
	float * vet=Histogram(img);
	for(c=1;c<256;c++){
		vet[c]+=vet[c-1];
	}
  return vet;
}

/* Equaliza o histograma, alterando a propria imagem. */
void HistogramEqualization(Image *img) {
	float * vet=AccHistogram(img);
	float aux;
	int c=0,tam=((img->ncols)*(img->nrows));
	while(c<tam){
		aux=255*(vet[img->val[c]]);
		img->val[c]=aux;
		aux-=img->val[c];
		if(aux>=0.5){
			img->val[c]++;
		}
		c++;
	}
	free(vet);
}

/* Recorta um retangulo representado pelos pontos (x0,y0) no
 * canto superior esquerdo e (x1,y1) no canto inferior
 * direito. Devolve o retangulo recortado como uma nova imagem,
 * sem alterar a imagem original. */
Image *CropRectangle(Image *img, int x0, int y0, int x1, int y1) {
	Image * nova;
	nova=CreateImage(x1-x0+1,y1-y0+1);
	int back=x0,c=0,ncol=img->ncols;
	while(y0<=y1){
		x0=back;
		while(x0<=x1){
			nova->val[c]=img->val[(y0*ncol)+x0];
			c++;
			x0++;
		}
		y0++;
	}
  return nova;
}

/*BBE foi utilizado nesse programa*/
